%include "boot.inc"
org 0x7c00
[bits 16]
xor ax,ax ; eax=0 
;初始化段寄存器
mov ds,ax
mov ss,ax
mov es,ax
mov fs,ax
mov gs,ax

;初始化栈指针
mov sp,0x7c00
mov ax,LOADER_START_SECTOR
mov bx,LOADER_START_ADDRESS
mov cx,LOADER_SECTOR_COUNT
load_bootloader:
    push ax
    push bx
    call asm_read_hard_disk 	;读取硬盘
    add sp,4
    inc ax
    add bx,512
    loop load_bootloader
jmp 0x0000:0x7e00	;跳转到 bootloader
jmp $	;死循环

;asm_read_hard_disk(memory,block)
;加载逻辑扇区号为block的扇区到内存地址memory
asm_read_hard_disk:
;从硬盘读取一个逻辑扇区
;参数列表
;cx序号
;ds:bx=读取数据的存放地址
;返回值
;bx=bx+512

    push bp
    mov bp,sp
    push ax
    push bx
    push cx
    push dx

    mov ax,[bp+2*3]	;逻辑扇区低16位
    mov dx,0x1f3	;0x1f3	
    out dx,al		;lba地址7-0
    
    inc dx		;0x1f4
    mov al,ah
    out dx,al		;lba地址15-8

    xor ax,ax
    inc dx		;0x1f5
    out dx,al		;lba地址23-16

    inc dx		;0x1f6
    mov al,ah
    and al,0x0f
    or al,0xe0		;31-25位逻辑扇区的设置位
    out dx,al		;lba地址27-24

    mov dx,0x1f2	;0x1f2
    mov al,1
    out dx,al		;读取一个扇区

    mov dx,0x1f7	;0x1f7
    mov al,0x20		;读命令
    out dx,al

    ;等待其他操作结束
    .waits:
        in al,dx	;dx=0x1f7
  	and al,0x88
	cmp al,0x08	;仅比较第3和7位判断是否准备
	jnz .waits   

    ;读取512字节到ds:bx
    mov bx,[bp+2*2]
    mov cx,256		;每次读取一个字，即两个字节，256次即可
    mov dx,0x1f0	;0x1f0
    .readw:
	in ax,dx
	mov [bx],ax
	add bx,2
	loop .readw
    pop dx
    pop cx
    pop bx
    pop ax
    pop bp
    ret

asm_read_hard_disk_chs:
; chs model    al扇区数 ch柱面 cl扇区 dh磁头 dl驱动器  es:bx 缓冲区地址
; 驱动器号 80h 磁道扇区数 63 每柱面磁头(道)数 18
; lba=(cylinder*headPerCylinder18+head)*sectorPerTrack63+sector-1
; cylinder= lba/(sectorPerTrack63*headPerCylinder18)
; head=(lba/sectorPerTrack63)%headPerCylinder18
; sector=lba%sectorPerTrack63+1
; lba model 已知 cx为扇区 28 位编号，ds:bx 读取数据地址
; chs return result cf=0,ah=0,al 传输扇区数 否则 ah为状态代码
    push eax
    push ebx
    push ecx
    push edx
    
    call caculate
    mov ah,02h
    mov al,1
    mov dl,80h
    int 13h
    
    pop edx
    pop ecx
    pop ebx
    pop eax
    ret
caculate:
    push ebx
    push esi
    
    mov ebx,0
    mov bx,cx	;lba
    mov ecx,0
    
    mov edx,0
    mov eax,ebx
    mov esi,63
    idiv esi
    mov cl,dl	;sector
    inc cx
    
    mov edx,0
    mov esi,18
    idiv esi
    mov dh,dl	;head
    mov ch,al	;cylinder
    
    pop esi
    pop ebx
    ret

times 510 - ($-$$) db 0
db 0x55,0xaa
